#include "isignal.h"

ISignal::ISignal()
{
	m_destroyed = false;
}

ISignal::~ISignal()
{
	if (!m_destroyed)
		Destroy();
}

void ISignal::Init()
{		
#ifdef WIN32
	m_event = ::CreateEvent(NULL, FALSE, FALSE, NULL);
#else
	pthread_mutex_init(&m_mutex, NULL);
	pthread_cond_init(&m_event, NULL);		
#endif
}

void ISignal::Destroy()
{
	if (m_destroyed)
		return;

#ifdef WIN32
	SetEvent(m_event);
	CloseHandle(m_event);
	m_destroyed= true;
#else
	pthread_mutex_lock(&m_mutex);
	pthread_cond_signal(&m_event);
	pthread_cond_destroy(&m_event);
	m_destroyed = true;
	pthread_mutex_unlock(&m_mutex);
	pthread_mutex_destroy(&m_mutex);
#endif
}

int ISignal::Wait(unsigned int waitTime /*=INFINITE*/)
{
	if ( m_destroyed ) return 0;
#ifdef WIN32
	DWORD dwRet = WaitForSingleObject(m_event, waitTime);
	if (dwRet == WAIT_OBJECT_0)
		return 1;
	else
		return 0;
#else
	int err = pthread_mutex_lock(&m_mutex);
	if (err != 0 || m_destroyed) {
		pthread_mutex_unlock(&m_mutex);
		return 0;
	}
	
	struct timespec timeout;
	timeout.tv_sec = time(0)+waitTime/1000;
	timeout.tv_nsec = (waitTime%1000)*1000;
	err = pthread_cond_timedwait(&m_event, &m_mutex, &timeout);
	pthread_mutex_unlock(&m_mutex);
	if ((err != 0 && err != ETIMEDOUT) || m_destroyed)
		return 0;
	else return 1;
#endif
}

void ISignal::Signal()
{
#ifdef WIN32
	SetEvent(m_event);
#else
	pthread_mutex_lock(&m_mutex);
	pthread_cond_signal(&m_event);
	pthread_mutex_unlock(&m_mutex);
#endif
}
